﻿// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Windows;
using System.Windows.Controls;

namespace Coding4Fun.Chair.Cockpit.Controls
{
	/// <summary>
	/// Interaction logic for Reticule.xaml
	/// </summary>
	public partial class Reticule : UserControl
	{
        private bool _isShowing;
        private bool _forceSet;
        private double _width;
        private double _height;
        private double _halfIndicator;
        private const double SpeedVisible = 1.3;

        public Reticule()
        {
            InitializeComponent();

            Hide(true);
            Loaded += Reticule_Loaded;
        }

        void Reticule_Loaded(object sender, RoutedEventArgs e)
        {
            _halfIndicator = uxVerticalIndicator.ActualHeight / 2;

            _width = ActualWidth;
            _height = ActualHeight;

            _forceSet = true;

            Horizontal = _width / 2;
            Vertical = _height / 2;
            
            _forceSet = false;
        }

        public double GetRelativeX()
        {
			return CalculatedXSpeed(Horizontal, _width);
        }

        public double GetRelativeY()
        {
            return CalculatedYSpeed(Vertical, _height);
        }

        private static double CalculatedYSpeed(double value, double size)
        {
			return KeepAbsoluteBounds(1 - (value / (size / 2d)), SpeedVisible);
        }

        private static double CalculatedXSpeed(double value, double size)
        {
			return KeepAbsoluteBounds((value / (size / 2d)) - 1, SpeedVisible);
        }

		public static double KeepAbsoluteBounds(double value, double max)
		{
			return (Math.Abs(value) <= max) ? value: 0;
		}

		private double _horizontal;
		public double Horizontal
		{
			get { return _horizontal; }
			set
			{
				_horizontal = value- _halfIndicator;

                if (_forceSet || _isShowing && Utilities.CheckBounds(Horizontal, 0, _width))
                    Utilities.SetMargin(uxHorizontalIndicator, Horizontal, 0);
			}
		}

		private double _vertical;
        public double Vertical
        {
            get { return _vertical; }
            set
            {
				_vertical = value -_halfIndicator;

                if(_forceSet || _isShowing && Utilities.CheckBounds(Vertical, 0, _height))
                    Utilities.SetMargin(uxVerticalIndicator, 0, Vertical);
            }
        }

	    public Point Position
		{
			get { return new Point { X = Horizontal, Y = Vertical }; }
			set
			{
				Horizontal = value.X;
				Vertical = value.Y;

                if (Utilities.CheckBounds(Vertical, 0, _height * SpeedVisible) &&
                    Utilities.CheckBounds(Horizontal, 0, _width * SpeedVisible))
                    Show();
                else
                    Hide();
			}
		}

		private void Show()
		{
            if (!_isShowing)
			{
				VisualStateManager.GoToState(this, "ShowState", true);

                _isShowing = true;
			}
		}
		private void Hide(Boolean immediately = false)
		{
            if (_isShowing)
			{
				VisualStateManager.GoToState(this, "HideState", !immediately);

                _isShowing = false;
			}
		}
	}
}